package com.nineclock.system.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.message.enums.MessageTypeEnum;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.system.dto.*;
import com.nineclock.system.feign.SysUserFeign;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.plugin2.message.Message;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    SysCompanyMapper companyMapper;
    @Autowired
    SysCompanyUserMapper companyUserMapper;
    @Autowired
    RedisTemplate<String,String> redisTemplate;
    @Autowired
    SysRoleMapper roleMapper;
    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;


    //查询当前的企业信息

    @Override
    public SysCompanyDTO queryCompanyInfo() {
        //从线程中获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //根据企业id获取企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if (company == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        //把pojo转换为dto对象
        SysCompanyDTO companyDTO = BeanHelper.copyProperties(company, SysCompanyDTO.class);
        return companyDTO;
    }



    //阿里云 文件存储的 客户端对象
    @Autowired
    OSS oss;
    @Autowired
    OssProperties ossProperties;


    @Override
    public String uploadOss(MultipartFile file) throws IOException {
        //1.健壮性的判断
        if (file==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);

        }

        //2.文件大小的限制
        if (file.getSize() > NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        //3.文件的类型的判断
        String contentType = file.getContentType();
        //如果contentType不等于空,并且 contentType在这三个文件限制之中 取反
        if (!(contentType != null && NcConstant.ALLOWED_IMG_TYPES.contains(contentType))){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        //4.生成唯一的文件名
        //String key = file.getOriginalFilename();
        String uuid = UUIDUtils.getUUID();
        //获取文件名
        String name = file.getOriginalFilename();//获取原始文件名
        //找到最后一个点所在的索引name.indexOf(".")
        //从点开始截取
        String extendsName = name.substring(name.indexOf("."));
        //拼接成一个文件名  xxx.jpg, 上传到oss
        String key = uuid + extendsName;
        log.info("key" + key);

        //5.上传文件
        PutObjectResult putObjectResult = oss.putObject(ossProperties.getBucketName(), key, file.getInputStream());
        log.info(putObjectResult.toString());//toString将你所要显示的内容以字符串的形式显示出来

        //返回最终的url https://nineclock02.oss-cn-beijing.aliyuncs.com/test.jpg
        /*aliyun.oss.host=https://%s.oss-cn-beijing.aliyuncs.com/
           ossProperties.getHost()=aliyun.oss.host=https://%s.oss-cn-beijing.aliyuncs.com
           ossProperties.getBucketName()=nineclock02 替换掉了%s
          key = 文件名
           */
        String imgPath = String.format(ossProperties.getHost(),ossProperties.getBucketName()) + key;

        log.info("imgPath" + imgPath);


        return imgPath;
    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        //1.健壮性的判断
        if (sysCompanyDTO==null || sysCompanyDTO.getLogo()==null || sysCompanyDTO.getName()==null){
            throw  new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //从当前线程中获取到当前企业的id
        Long companyId = CurrentUserHolder.get().getCompanyId();


        //2.获取当前企业的信息
        SysCompany company = companyMapper.selectById(companyId);


        //3.更新当前企业的信息
        if (company==null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        company.setName(sysCompanyDTO.getName());
        company.setLogo(sysCompanyDTO.getLogo());

        //4.持久化到数据库
        companyMapper.updateById(company);
    }

    @Override
    public SysCompanyUserDTO queryCurrentAdmin() {
        //获取企业
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取系统主管理员
        SysCompanyUser companyUser = companyMapper.queryCurrentAdmin(companyId);
        if (companyUser == null){
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        return BeanHelper.copyProperties(companyUser,SysCompanyUserDTO.class);
    }





    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {
        if (sysChangeMainManagerDTO ==  null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //1.获取即将要称为管理员的id 根据userId获取新管理员的员工信息
        SysCompanyUser companyUser = companyUserMapper.selectById(sysChangeMainManagerDTO.getUserId());

        if (companyUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //2.校验验证码
        String key = SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + companyUser.getMobile();
        //获取redis中的验证码
        String realCode = redisTemplate.boundValueOps(key).get();

        //校验验证码
        if(!(realCode !=null && realCode.equals(sysChangeMainManagerDTO.getCode()))){
            throw  new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }

        //3.获取老管理员的id
        SysCompanyUser currentAdmin = companyMapper.queryCurrentAdmin(CurrentUserHolder.get().getCompanyId());
        //获取系统主管理员的 角色信息
        LambdaQueryWrapper<SysRole> roleQw = new LambdaQueryWrapper<>();
        roleQw.eq(SysRole::getCompanyId,CurrentUserHolder.get().getCompanyId());
        roleQw.eq(SysRole::getRoleName,"ROLE_ADMIN_SYS");
        SysRole role = roleMapper.selectOne(roleQw);

        //4.删除老管理员的id
        LambdaQueryWrapper<SysCompanyUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUserRole::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysCompanyUserRole::getCompanyUserId, currentAdmin.getId());
        wrapper.eq(SysCompanyUserRole::getRoleId, role.getId());
        companyUserRoleMapper.delete(wrapper);

        //5.设置新管理员
        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setRoleId(role.getId());
        companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
        companyUserRole.setCompanyUserId(companyUser.getId());

        companyUserRoleMapper.insert(companyUserRole);
    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        if (keyword == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();

        wrapper.like(SysCompany::getName,keyword);

        List<SysCompany> companyList = companyMapper.selectList(wrapper);

        if (companyList!=null) {
            return BeanHelper.copyWithCollection(companyList,SysCompanyDTO.class);
        }
        return null;
    }

    @Autowired
    SysUserMapper userMapper;

    @Autowired
    RocketMQTemplate mqTemplate;

    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO applyJoinCompanyUserDTO) {
        //1. 健壮性判断
        if (applyJoinCompanyUserDTO==null || applyJoinCompanyUserDTO.getUserName()==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //2. 更新用户表
        SysUser user = userMapper.selectById(applyJoinCompanyUserDTO.getUserId());
        if (user==null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        user.setUsername(applyJoinCompanyUserDTO.getUserName());
        user.setEmail(applyJoinCompanyUserDTO.getEmail());
        user.setUpdateTime(new Date());
        user.setLastLoginCompanyId(applyJoinCompanyUserDTO.getCompanyId());

        userMapper.updateById(user);
        //3. 员工表新增数据
        SysCompanyUser companyUser = new SysCompanyUser();
        companyUser.setUserId(applyJoinCompanyUserDTO.getUserId());
        companyUser.setCompanyId(applyJoinCompanyUserDTO.getCompanyId());
        companyUser.setCompanyName(applyJoinCompanyUserDTO.getCompanyName());
        companyUser.setPost(applyJoinCompanyUserDTO.getPost());
        companyUser.setTimeEntry(new Date());
        companyUser.setRemark(applyJoinCompanyUserDTO.getApplyReason());
        companyUser.setEnable((short)0);
        companyUser.setCreateTime(new Date());
        companyUser.setMobile(applyJoinCompanyUserDTO.getUserName());
        companyUser.setUserName(applyJoinCompanyUserDTO.getUserName());
        companyUser.setImageUrl(applyJoinCompanyUserDTO.getImageUrl());
        //存储到数据库
        companyUserMapper.insert(companyUser);

        //TODO 推送申请消息 给系统管理员

        //获取系统主管理员
        SysCompanyUser currentAdmin = companyMapper.queryCurrentAdmin(applyJoinCompanyUserDTO.getCompanyId());


        NcMessage message = new NcMessage();

        message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType()); //消息类型 团队推送
        message.setCreateTime(new Date());
        message.setCompanyId(applyJoinCompanyUserDTO.getCompanyId() + "");
        message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle()); //消息标题
        message.setContent(applyJoinCompanyUserDTO.getUserName() + "申请加入企业, 请及时审批");//提示消息内容

        message.setUseStatus(0);
        message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience());
        message.setTargets(Arrays.asList(currentAdmin.getMobile())); //推送的目标(系统管理员的手机号)
        message.setApproveStatue(0);

        //申请人信息
        message.setApplyUserId(user.getId());
        message.setApplyUsername(user.getUsername());
        //审批人信息
        message.setApproveUserId(currentAdmin.getUserId());
        message.setApproveUsername(currentAdmin.getUserName());


        mqTemplate.convertAndSend("messagePushTopic",message);
    }


    //审核加入企业
    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
        /**
         * 1. 更新数据库的状态
         * 2. 推送消息
         *
         */

        if (sysAllowedJoinCompanyUserDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //1. 更新数据库的状态
        Long applyUserId = sysAllowedJoinCompanyUserDTO.getApplyUserId();

        //根据企业id, 员工ID查询, 员工信息
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<SysCompanyUser>();
        wrapper.eq(SysCompanyUser::getUserId,applyUserId);
        //申请人 员工信息
        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);
        companyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());
        companyUser.setEnable((short)(sysAllowedJoinCompanyUserDTO.getApproved() ? 1 : 0));

        companyUserMapper.updateById(companyUser);




        //2. 推送消息
            //2.1 推送 通知员工 审核完成或者失败

        NcMessage message = new NcMessage();
        message.setMessageType(MessageTypeEnum.COMPANY_APPLY_PASS.getType());
        message.setCreateTime(new Date());
        message.setCompanyId(companyUser.getCompanyId() + "");
        message.setTitle(MessageTypeEnum.COMPANY_APPLY_PASS.getType());
        message.setContent(companyUser.getUserName() + "加入企业请求,申请"+ (sysAllowedJoinCompanyUserDTO.getApproved() ? "通过" : "未通过" ));
        message.setUseStatus(1);
        //申请人信息
        message.setApplyUserId(companyUser.getUserId());
        message.setApplyUsername(companyUser.getUserName());
        //审批人信息
        message.setApproveUsername(CurrentUserHolder.get().getUsername());
        message.setApproveUserId(CurrentUserHolder.get().getId());
        message.setApproveResult(sysAllowedJoinCompanyUserDTO.getRemark());



        mqTemplate.convertAndSend("messagePushTopic",message);
        mqTemplate.convertAndSend("allowedJoinCompanyTopic",sysAllowedJoinCompanyUserDTO.getNotifyMsgId());



            //2.2 推送 更新mongo





    }
}
